" add undo moment for F6 fix
" reopening 'workspace'
" Allow 'alt tab' rearranging behavior for gT, also, add gtn gtp (with / without reloading)
" Lettered menus for buffers?? ie, similar to Windows [U]ndo
" Fit insermenu to window width (actually... requires dynamic ... naaa)
" search across multiple files
au!
mapc
mapc!
no @ <Esc>
no! @ <Esc>
cno @ <C-C>
map [3~ 
map! [3~ 
map OP <F1>
map! OP <F1>
map OQ <F2>
map! OQ <F2>
map OR <F3>
map! OR <F3>
map OS <F4>
map! OS <F4>
map [15~ <F5>
map! [15~ <F5>
map! [2~ <C-O>x
map [2~ <Del>
no  <F1> !
no! <F1> !
no  <F2> @
no! <F2> @
no  <F3> #
no! <F3> #
no  <F4> $
no! <F4> $
no  <F5> %
no! <F5> %
no  <F6> ^
no! <F6> ^
no  <F7> &
no! <F7> &
no  <F8> *
no! <F8> *
nnoremap <F9> <C-O>
nnoremap <F10> <C-I>
set nowrap linebreak sidescroll=1 ignorecase smartcase incsearch backspace=2
set tabstop=4 history=150 mouse=a ttymouse=xterm hidden listchars=tab:>\ ,eol:<
set wildmenu wildmode=list:longest,full display=lastline modeline t_Co=256
syntax off
cd /sdcard/q335writings
so abbrev
au VimEnter * if !argc()|e main.txt|en

fun! Repeatchar(char,count)
	return repeat(a:char,a:count)	
endfun
nmap <C-J> <C-M>
nno <silent> <C-M> :<C-U>exec 'norm! a'.Repeatchar(nr2char(getchar()),v:count1)<CR>
nno <silent> <space> :<C-U>exec 'norm! i'.Repeatchar(nr2char(getchar()),v:count1)<CR>

cnorea <expr> we ((getcmdtype()==':' && getcmdpos()<4)? 'w\|e' :'we')
cnorea <expr> wf ((getcmdtype()==':' && getcmdpos()<4)? 
\ 'w\|e\|norm! gggqG':'we')
cnorea <expr> waq ((getcmdtype()==':' && getcmdpos()<5)? 'wa\|q':'waq')
cnorea <expr> ws ((getcmdtype()==':' && getcmdpos()<4)? 'w\|so%':'ws')
cnorea <expr> wd ((getcmdtype()==':' && getcmdpos()<4)? 'w\|bd':'wd')
cnorea <expr> wsd ((getcmdtype()==':' && getcmdpos()<5)? 'w\|so%\|bd':'wsd')

let g:PrevFT=[0,0]
fun! MultilineFT(command)
	if a:command==';'
		let com=g:PrevFT[0]
	elseif a:command==','		
		let ascii=char2nr(g:PrevFT[0])
		let com=nr2char((ascii>95)*(ascii-32)+(ascii<=95)*(ascii+32))
	else
		let g:PrevFT=[a:command,nr2char(getchar())]
		let com=a:command
	endif
	if com==#'F'
		call search(g:PrevFT[1],'bW')
	elseif com==#'T'
		exe (search(g:PrevFT[1],'bW')? 'norm! l' : '')
	elseif com==#'f'
		exe (search(g:PrevFT[1],'W')? 'norm! l' : '')
	elseif com==#'t'
		call search(g:PrevFT[1],'W')
	endif
endfun
fun! MultilinenFT(command)
	if a:command==';'
		let com=g:PrevFT[0]
	elseif a:command==','		
		let ascii=char2nr(g:PrevFT[0])
		let com=nr2char((ascii>95)*(ascii-32)+(ascii<=95)*(ascii+32))
	else
		let g:PrevFT=[a:command,nr2char(getchar())]
		let com=a:command
	endif
	if com==#'F'
		call search(g:PrevFT[1],'bW')
	elseif com==#'T'
		norm! h
		call search(g:PrevFT[1],'bW')
		norm! l
	elseif com==#'t'
		norm! l
		call search(g:PrevFT[1],'W')
		norm! h
	elseif com==#'f'
		call search(g:PrevFT[1],'W')
	endif
endfun
nn <silent> F :call MultilinenFT('F')<CR>
nn <silent> T :call MultilinenFT('T')<CR>
nn <silent> f :call MultilinenFT('f')<CR>
nn <silent> t :call MultilinenFT('t')<CR>
nn <silent> ; :call MultilinenFT(';')<CR>
nn <silent> , :call MultilinenFT(',')<CR>
ono <silent> F :call MultilineFT('F')<CR>
ono <silent> T :call MultilineFT('T')<CR>
ono <silent> f :call MultilineFT('f')<CR>
ono <silent> t :call MultilineFT('t')<CR>
ono <silent> ; :call MultilinenFT(';')<CR>
ono <silent> , :call MultilinenFT(',')<CR>

fun! PunchIn() "requires !export TZ=EST5EDT
	if bufname('%')!=#'Timecard'
		split Timecard
	endif
	let now=strftime("%l:%M %m/%d... punch [i]n / [o]ut /[q]?")
	echoh Constant | redraw | echo now 
	let io=nr2char(getchar())
	if io=~?'[io]'
		exe (search('^'.now[6:10])? 'norm! A' : 'norm! Go'.now[6:10])
		\.(io==?'i'? ' ' : '>').now[0:4]
		redraw | echo "...done" | call getchar()
	endif
	if io=~?'[ioq]'
		exe (winnr('$')>1? 'q' : 'e #')
	endif
	redraw | echo "" | echoh End	
endfun
nnoremap `T :call PunchIn()<CR>

fun! CapWait(prev)
	redraw
	let next=nr2char(getchar())
	if next=~'[.?!\r\n[:blank:]()]'
		exe 'normal! i' . next . "\<Right>"
		return CapWait(next)
	elseif next=~'[\e\@]'
	return "\<del>"
	elseif a:prev=~'[\r\n[:blank:]]'
		return toupper(next) . "\<del>"
	else
		return next . "\<del>"
	endif
endfun
fun! CapHere()
	let trunc = getline(".")[0:col(".")-2] 
	return col(".")==1 ? CapWait("\r")
	\ : trunc=~'[?!.]\s*$\|^\s*$' ? CapWait(trunc[-1:-1]) : "\<del>"
endfun
fun! InitTextFile()
"	syntax region txtShow start=/\t/ end=/\t\|\S\n/
"	syntax region txtHide start=/>\t/ end=/\t\|\S\n/
	hi link txtShow Constant
	hi link txtHide NonText
	iab <buffer> i I
	iab <buffer> Id I'd
	iab <buffer> id I'd
	iab <buffer> im I'm
	iab <buffer> Im I'm
	ino <buffer> <silent> <F6> <C-O>mt<C-O>:if search("'",'b')\|exe'norm! x'\|en<CR><C-O>`t
	im <buffer> <silent> . ._<Left><C-R>=CapWait('.')<CR>
	im <buffer> <silent> ? ?_<Left><C-R>=CapWait('?')<CR>
	im <buffer> <silent> ! !_<Left><C-R>=CapWait('!')<CR>
	im <buffer> <silent> <CR> <CR>_<Left><C-R>=CapWait("\r")<R>
	im <buffer> <silent> <NL> <NL>_<Left><C-R>=CapWait("\n")<CR>
	nm <buffer> <silent> O O_<Left><C-R>=CapWait("\r")<CR>
	nm <buffer> <silent> o o_<Left><C-R>=CapWait("\r")<CR>
	nm <buffer> <silent> a a_<Left><C-R>=CapHere()<CR>
	nm <buffer> <silent> A $a_<Left><C-R>=CapHere()<CR>
	nm <buffer> <silent> i i_<Left><C-R>=CapHere()<CR>
	nm <buffer> <silent> I I_<Left><C-R>=CapHere()<CR>
	nm <buffer> <silent> s s_<Left><C-R>=CapHere()<CR>
	nm <buffer> <silent> cc cc_<Left><C-R>=CapHere()<CR>
	nm <buffer> <silent> cw cw_<Left><C-R>=CapHere()<CR>
	nm <buffer> <silent> R R_<Left><C-R>=CapHere()<CR>
	nm <buffer> <silent> C C_<Left><C-R>=CapHere()<CR>
	if getline(1)=~'tw='	
		nmap <buffer> A }b$a
		nmap <buffer> I {w0i
	endif
endfun
au BufNewFile,BufRead *.txt call InitTextFile()
au BufNewFile *.txt exe "norm! i>\tvim: set nowrap ts=4 tw=66 fo=aw:"

let g:Menu=["r: '!rm '.(expand('%:h')=='.'? '':expand('%:h').'/')"
\ .".(expand('%:t')[0]=='.'? '':'.').expand('%:t').'.swp'",
\ "t: 'let g:StartTime=(g:StartTime ? 0 : localtime())'",
\ "h: 'help '.expand('<cword>')",
\ "f: 'call FingerPaintOn()'",
\ "F: 'call FingerPaintOff()'",
\ "s: 'se ls='.(2*!&ls)",
\ "@: ''"]
let g:MenuStr=join(map(copy(g:Menu),
\ "(len(v:val)>44? v:val[:20].' .. '.v:val[-20:] : v:val)"),"\n")
let g:MenuIndex=repeat([-1],200)
let idxnr=0 | for i in g:Menu
	let g:MenuIndex[char2nr(i[0])]=idxnr
	let idxnr+=1
endfor | unlet idxnr
fun! InsertMenu()
	echo g:MenuStr
	let cmd=eval(g:Menu[g:MenuIndex[getchar()]][3:])
	redraw | return cmd
endfun
fun! BufferMenu(count)
	let bufstr="\n" | let idx=[0]
	for b in range(1, bufnr('$'))
		let bufstr.=buflisted(b)? (len(add(idx,b))-1)
		\ .(bufnr('%')==b? '*':' ').' '.matchstr(bufname(b),'[^/]*$')."\n":''
	endfor
	echoh Constant | echo bufstr | echoh None
	let sel=a:count==0? nr2char(getchar()) : a:count
	if sel==?'x'
		let lst=join(map(split(input("Delete buffers ")),'idx[v:val]'))
		if lst
			exe 'redraw | bd! '.lst
			call BufferMenu(0)
		endif
	elseif str2nr(sel)
		exe 'redraw | b '.idx[sel]
	endif
endfun
nn gn :b#<CR>
nn gt :<C-U>call BufferMenu(v:count)<CR>
nn gc :exe InsertMenu()<CR>

se wiw=1
let s:Dots  =repeat('.',200)
let s:Dashes=repeat('-',200)
let s:Spaces=repeat(' ',200)
let s:Speed =[1,2,3,4,5,6,7,8,9,10,11,12]
let g:MouseMode='InitScroll'
fun! InitScroll()
	let s:vesave=&ve | se ve=all
	let s:pP=[winnr(),winline(),wincol()]
	let g:MouseMode='OnScroll'
	let s:initCol=s:pP[2]
endfun
fun! OnScroll()
	let s:cP=[winnr(),winline(),wincol()]
	if s:cP[0]==s:pP[0]
		if s:initCol
			let s:initCol=(abs(s:cP[2]-s:initCol)<10)*s:initCol
    		let difC=0
		else
    		let difC=s:cP[2]-s:pP[2]
		endif
		let difR=s:cP[1]-s:pP[1]
    	let s:pP=s:cP
		let cmd=(difC>0? difC."z\<left>":difC<0? (-difC)."z\<right>":'')
		\ .(difR>0? s:Speed[difR]."\<C-Y>":difR<0? s:Speed[-difR]."\<C-E>":'')
		if cmd
			exe 'norm! '.cmd
	    	redraw | echo s:Dots[2:line('w0')*&columns/line('$')]
	    elseif line('.')==line('$')
	    	exe "norm! \<C-Y>"
	    endif
	else
		let g:MouseMode='OnResize'
		call OnResize()
	endif
endfun
fun! OnVisual()
	let cdiff=virtcol("'v")-wincol()
	let rdiff=line("'v")-line(".")
	echo rdiff.(s:Spaces[1:(cdiff>0? wincol():virtcol("'v"))]
	\ .s:Dashes[1:abs(cdiff)])[len(rdiff):]
	if line('.')==line('w$')
		exe "norm! \<C-E>"
	elseif line('.')==line('w0')
		exe "norm! \<C-Y>"
	endif
endfun
let s:dirs=['k','j','l','h']
let s:opp =['j','k','h','l']
fun! GetResDir()
	for i in (s:cP[0]>s:pP[0]? [1,2]:[0,3])
		exe s:cP[0].'winc w|winc '.s:opp[i]
		if winnr()==s:pP[0]
			return s:dirs[i]
		endif
	endfor
	return 'U'
endfun
fun! ResizeWinU(winnr,L)
endfun
fun! ResizeWinX(winnr,L)
endfun
fun! WinPushK(winnr,L)
	exe a:winnr.'winc w|winc k'
	let moved=0
	let iwin=a:winnr
	let todo=[]
	while iwin!=winnr() && a:L>moved
		let iwin=winnr()
		let curL=winheight(0)-1
		let moved+=insert(todo,[iwin,(curL>a:L-moved? a:L-moved : (curL>0)*curL)])[0][1]
		winc k
	endwhile
	let sum=0
	for i in todo
		let sum+=i[1]
		exe i[0].'winc w|res -'.sum
	endfor
endfun
fun! WinPullK(winnr,L)
	exe a:winnr.'winc w|winc k'
   	exe 'res +'.(winnr()!=a:winnr? min([winheight(a:winnr)-1,a:L]):0)
endfun
fun! WinPushH(winnr,L)
	exe a:winnr.'winc w|winc h'
	let moved=0
	let iwin=a:winnr
	let todo=[]
	while iwin!=winnr() && a:L>moved
		let iwin=winnr()
		let curL=winwidth(0)-1
		let moved+=insert(todo,[iwin,(curL>a:L-moved? a:L-moved : (curL>0)*curL)])[0][1]
		winc h
	endwhile
	let sum=0
	for i in todo
		let sum+=i[1]
		exe i[0].'winc w|vert res -'.sum
	endfor
endfun
fun! WinPullH(winnr,L)
	exe a:winnr.'winc w|winc h'
   	exe 'vert res +'.(winnr()!=a:winnr? min([winwidth(a:winnr)-1,a:L]):0)
endfun
fun! WinPushJ(winnr,L)
	exe a:winnr.'winc w|winc j'
	let moved=0
	let curwin=a:winnr
	while moved<a:L && winnr()!=curwin
		let moved+=winheight(0)-1
		let curwin=winnr()
		winc j
	endwhile
	exe a:winnr.'winc w|res +'.min([a:L,moved])
endfun
fun! WinPullJ(winnr,L)
	exe a:winnr.'winc w|winc j'
   	if winnr()!=a:winnr
		exe a:winnr.'winc w|res -'.min([winheight(a:winnr)-1,a:L])
   	endif
endfun
fun! WinPushL(winnr,L)
	exe a:winnr.'winc w|winc l'
	let moved=0
	let curwin=a:winnr
	while moved<a:L && winnr()!=curwin
		let moved+=winwidth(0)-1
		let curwin=winnr()
		winc l
	endwhile
	exe a:winnr.'winc w|vert res +'.min([a:L,moved])
endfun
fun! WinPullL(winnr,L)
	exe a:winnr.'winc w|winc l'
   	if winnr()!=a:winnr
		exe a:winnr.'winc w|vert res -'.min([winwidth(a:winnr)-1,a:L])
   	endif
endfun
fun! OnResize()
	let s:cP=[winnr(),winline(),wincol()]
	if s:pP[0]!=s:cP[0]
		let s:dir=GetResDir()
		if s:dir=='k'
			call WinPushK(s:pP[0],winheight(s:cP[0])-s:cP[1]+1)
			let s:pP[1]=1
		elseif s:dir=='j'
			call WinPushJ(s:pP[0],s:cP[1])
			let s:pP[1]=winheight(s:pP[0])
		elseif s:dir=='h'
			call WinPushH(s:pP[0],winwidth(s:cP[0])-s:cP[2]+1)
			let s:pP[2]=1
		elseif s:dir=='l'
			call WinPushL(s:pP[0],s:cP[2])
			let s:pP[2]=winwidth(s:pP[0])
		endif
	elseif s:pP!=s:cP
		if s:dir=='j'
			call WinPullJ(s:pP[0],winheight(s:cP[0])-s:cP[1])
			let s:pP[1]=winheight(s:pP[0])
		elseif s:dir=='k'
			call WinPullK(s:pP[0],s:cP[1]-1)
			let s:pP[1]=1
		elseif s:dir=='l'
			call WinPullL(s:pP[0],winwidth(s:cP[0])-s:cP[2])
			let s:pP[2]=winwidth(s:pP[0])
		elseif s:dir=='h'
			call WinPullH(s:pP[0],s:cP[2]-1)
			let s:pP[2]=1
		endif
	endif
endfun
fun! OnRelease()
	if g:MouseMode=='OnVisual'
		norm! v`v
	else
		exe 'se ve='.s:vesave
	endif
	let g:MouseMode='InitScroll'
endfun
fun! FingerPaintOn()
	ec 'Brush? ' | let brush=nr2char(getchar())
	let s:vesave=&ve | se ve=all
	exe 'nn <silent> <leftmouse> <leftmouse>R'.brush
	exe 'ino <silent> <leftmouse> <leftmouse>'.brush
	ino <leftrelease> <Esc>
endfun
fun! FingerPaintOff()
	exe 'se ve='.s:vesave
	nn <silent> <leftmouse> <leftmouse>:call {g:MouseMode}()<CR>
	nn <silent> <leftrelease> <leftmouse>:call OnRelease()<CR>
	iunmap <leftrelease>
	iunmap <leftmouse>
endfun                                                              
nn <silent> <leftmouse> <leftmouse>:call {g:MouseMode}()<CR>
nn <silent> <leftrelease> <leftmouse>:call OnRelease()<CR>
vn <silent> <leftmouse> <Esc>mv<leftmouse>:let g:MouseMode='OnVisual'<CR>
	
let g:StartTime=0
fun! DispTime()
	return (g:StartTime ? strftime("%H:%M",localtime()-g:StartTime+18000) : '').strftime(" %l:%M %b %d ")
endfun
set stl=\ %l/%L:%c\ %<%F%y%=\ %{DispTime()}
